#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <fstream>

using namespace std;

const long long GCOV_DATA_MAGIC = 0x67636461u;
const long long GCOV_TAG_FUNCTION = 0x01000000u;
const long long GCOV_TAG_COUNTER_BASE = 0x01a10000u;
const long long GCOV_TAG_OBJECT_SUMMARY = 0xa1000000u;

/* value profile counter */
const long long GCOV_TAG_COUNTER_INTERVAL = 0x01a30000u;
const long long GCOV_TAG_COUNTER_POW2 = 0x01a50000u;
const long long GCOV_TAG_COUNTER_TOPN = 0x01a70000u;
const long long GCOV_TAG_COUNTER_IC = 0x01a90000u;
const long long GCOV_TAG_COUNTER_AVERAGE = 0x01ab0000u;
const long long GCOV_TAG_COUNTER_IOR = 0x01ad0000u;
const long long GCOV_TAG_COUNTER_TP = 0x01af0000u;

static int ReadFile (const string filename, vector<char>& out)
{       
    FILE* fp = fopen(filename.c_str(), "rb");
    if (!fp)
    {
        fprintf(stderr, "Failed to open: %s\n", filename.c_str());
        return 1;
    }
    
    const int bufSize = 4096;
    char buf[bufSize];
    size_t sz;
    while (sz = fread(buf, 1, bufSize, fp))
    {
         out.insert(out.end(), buf, buf + sz);
    }
    fclose(fp);
    return 0;
}       

static void SplitLines (const vector<char>& in, vector<string>& out)
{
    size_t pos = 0;
    for (size_t i = 0; i < in.size(); i++)
    {
	if (in[i] != '\r' && in[i] != '\n')
	{
	    continue;
	}
	out.push_back(string(in.begin() + pos, in.begin() + i));
	if (in[i] == '\r' && i + 1 < in.size() && in[i + 1] == '\n')
	{
	    i ++;
	}
	pos += 1;
    }
    if (pos < in.size())
    {
	out.push_back(string(in.begin() + pos, in.end()));
    }
}

static int WirteFile (string fileName, const vector<char> in, unsigned int valMax)
{
    if (in.size() < 12) {
        fprintf(stderr, "[!] Not enough size to wirte\n");
        return 1;
    }
    FILE* fp = fopen(fileName.c_str(), "wb");
    if (!fp)
    {
        fprintf(stderr, "[!] Fail to write: %s \n", fileName.c_str());
        return 1;
    }
    fwrite(in.data(), 1, 16, fp);
    unsigned int title[4] = {
        GCOV_TAG_OBJECT_SUMMARY,
        8,
        4,
        valMax
    };
    fwrite(title, 1, 16, fp);
    fwrite(in.data() + 16, 1, in.size() - 16, fp);

    fclose(fp);
    return 0;
}

int main()
{       
    const string filename = "spinlock.gcda";
    vector<char> out;
    ReadFile(filename, out);
    vector<string> modify;
    SplitLines(out, modify);
    WirteFile(filename, out, 0);
    std::ofstream file;
    file.open(filename, ios::out|ios::app);
    vector<char> zeros (14, 0);
    file.write(zeros.data(), zeros.size());
    file.close();
    return 1;
}

